package com.example.springredisdemo.configuration;

import com.example.springredisdemo.listener.MessageDelegate;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.Topic;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

import java.time.Duration;
import java.util.*;

/**
 * spring-data-redis文档：https://docs.spring.io/spring-data/redis/docs/2.1.8.RELEASE/reference/html/
 * 事务配置问题: https://www.jianshu.com/p/c9f5718e58f0 redis @Transaction
 */
@Configuration
@EnableCaching
public class RedisConfig {

    @Bean
    public Map<MessageListener,Collection<? extends Topic>> messageListener(List<MessageDelegate> messageDelegates) {
        Map<MessageListener,Collection<? extends Topic>> map = new HashMap<>();
        for(MessageDelegate messageDelegate : messageDelegates) {
            MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(messageDelegate,"onMessage");
            messageListenerAdapter.afterPropertiesSet();
            ArrayList<Topic> topics = new ArrayList<>();
            ChannelTopic channelTopic = new ChannelTopic(messageDelegate.getChannel());
            topics.add(channelTopic);
            map.put(messageListenerAdapter,topics);
        }

        return map;
    }

    /**
     * 配置 redis pub/sub
     * @param connectionFactory
     * @param messageListener
     * @return
     */
    @Bean
    public RedisMessageListenerContainer redisContainer(RedisConnectionFactory connectionFactory, Map<MessageListener, Collection<? extends Topic>> messageListener) {
        RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer();
        redisMessageListenerContainer.setConnectionFactory(connectionFactory);
        redisMessageListenerContainer.setMessageListeners(messageListener);
        return redisMessageListenerContainer;
    }


    /**
     * spring cache support
     * @param connectionFactory
     * @return
     */
    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        Map<String,RedisCacheConfiguration> map = new HashMap<>();
        map.put("test",RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(20)));
        return RedisCacheManager.builder(connectionFactory).withInitialCacheConfigurations(map).build();
    }
}
